<template>
  <div>
    <div :class="isDesktop ? 'px-ctn' : 'px-4 pb-2'">
      <Breadcrumb :breadcrumbs="breadcrumbs"></Breadcrumb>
    </div>
    <div class="d-flex flex-column" :class="isDesktop ? 'px-atc pt-4 gap-col-16' : 'px-4 gap-col-8'">
      <div
        class="d-flex justify-center flex-column align-center img-container"
        :class="{ 'load h_450 pt-0': !load && isDesktop, 'load h_200 pt-0': !load }"
      >
        <img
          v-show="load"
          :src="detailData?.cover_img"
          :alt="detailData?.title"
          @error="handleImageError"
          :class="{ err: detailData?.cover_img === ErrorNodataImage }"
        />
      </div>
      <div
        class="d-flex flex-row justify-space-between align-center"
        :class="{
          'mb-4 gap-row-16': isDesktop,
          'mb-4 gap-row-8': !isDesktop,
          'load h_50': !load,
          'mt-2': !load && !isDesktop,
        }"
      >
        <Link :href="`/blog/${prev?.url_address}`" @click="toPrev(prev?.url_address)" class="w-50">
          <div
            class="d-flex align-center"
            :class="isDesktop ? 'gap-row-16 font-size-14 font-weight-500 line-height-140' : 'gap-row-8'"
          >
            <Icon v-show="load" class="scaleX" :size="arrowIconSize" name="arrowRight"></Icon>
            <div v-show="load" class="ellipsis-multiple">{{ prev?.title }}</div>
          </div>
        </Link>
        <Link :href="`/blog/${next?.url_address}`" @click="toNext(next?.url_address)" class="w-50">
          <div
            class="d-flex align-center justify-end"
            :class="isDesktop ? 'gap-row-16 font-size-14 font-weight-500 line-height-140' : 'gap-row-8'"
          >
            <div v-show="load" class="ellipsis-multiple text-right">{{ next?.title }}</div>
            <Icon v-show="load" :size="arrowIconSize" name="arrowRight"></Icon>
          </div>
        </Link>
      </div>
      <div :class="{ 'load h_200': !load && isDesktop, 'load h_450': !load && !isDesktop }">
        <div
          class="d-flex flex-row justify-space-between align-center"
          :class="{ 'pb-1': isDesktop && load, 'pb-2 gap-row-8': !isDesktop, 'pb-0': isDesktop && !load }"
        >
          <div
            v-show="load"
            class="font-weight-400 line-height-140"
            :class="isDesktop ? 'font-size-14' : 'font-size-12'"
          >
            {{ getTime(detailData?.timstamp) }}
          </div>
          <Icon v-show="load" @click="shareLink(id)" class="pointer" :size="shareIconSize" name="shareBold"></Icon>
        </div>
        <div class="gap-col-16">
          <div
            v-show="load"
            class="font-weight-500 line-height-140"
            :class="isDesktop ? 'font-size-20' : 'font-size-16'"
          >
            {{ detailData?.title }}
          </div>
          <div
            v-show="load"
            class="font-weight-400 line-height-140 pre-line"
            :class="isDesktop ? 'font-size-16' : 'font-size-14'"
          >
            <div class="content" v-html="detailData?.content"></div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <Jsonld :schema="schema"></Jsonld>
</template>
<script setup>
import { computed, onActivated, onMounted, ref, shallowRef, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { storeToRefs } from 'pinia'
import { useAppStore } from '@/store/app'
import { useHeadStore } from '@/store/head'
import { $t } from '@/i18n'
import Breadcrumb from '@/components/common/Breadcrumb.vue'
import Jsonld from '@/components/common/Jsonld.vue'
import Link from '@/components/common/Link.vue'
import { useInfinite } from '@/compositions/request/infinite'
import { useCopyToClipboard } from '@/compositions/utils/copyToClipboard'
import API from '@/http'

const ErrorNodataImage = '/images/fail-placeholder.png'

const { toBlogArticleHead, toHomeHead } = useHeadStore()
onActivated(toBlogArticleHead)
const { isDesktop } = storeToRefs(useAppStore())
const route = useRoute()
const router = useRouter()

const id = ref(route.path.match(/\/blog\/(.*)/)[1])
const detailData = ref(null)
const load = ref(false)
const blogList = ref(null)
const prev = ref(null)
const next = ref(null)
const breadcrumbs = ref([
  { label: $t('meta.keywords.title'), to: '/' },
  { label: $t('title.blog'), to: '/blog' },
  { label: `${'Detailed page' || detailData.value.title}`, to: `/blog/${id.value}` },
])

// 取得部落格內頁資料
async function getDetail() {
  const data = { id: id.value }
  try {
    detailData.value = await API.Blog.detail({ data })
    console.log(route.fullPath)
    if (route.fullPath.includes('blog/')) {
      toBlogArticleHead(detailData.value)
    } else {
      toHomeHead()
    }
  } catch (e) {
    console.error(e)
  }
}
onMounted(() => {
  getDetail()
  init()
})
watch(detailData, (newValue) => {
  if (newValue) {
    breadcrumbs.value[2].label = detailData.value.title
    getTime()
    load.value = true
  }
})

// 取得部落格列表資料
const { dataList: items, init } = useInfinite({ request: API.Blog.list })
watch(items.value, (newItems) => {
  if (newItems) {
    blogList.value = newItems
    const currentIndex = blogList.value.indexOf(blogList.value.find(isId))
    updatePrevNext(currentIndex)
  }
})

function updatePrevNext(currentIndex) {
  // Prev
  if (currentIndex === 0) {
    prev.value = blogList.value[blogList.value.length - 1]
  } else {
    prev.value = blogList.value[currentIndex - 1]
  }
  // Next
  if (currentIndex === blogList.value.length - 1) {
    next.value = blogList.value[0]
  } else {
    next.value = blogList.value[currentIndex + 1]
  }
}
function isId(item) {
  return item.url_address === id.value
}

function toPrev(prevId) {
  load.value = false
  router.push({ path: `/blog/${prevId}` })
  id.value = prevId
  const currentIndex = blogList.value.indexOf(blogList.value.find(isId))
  updatePrevNext(currentIndex)
}
function toNext(nextId) {
  load.value = false
  router.push({ path: `/blog/${nextId}` })
  id.value = nextId
  const currentIndex = blogList.value.indexOf(blogList.value.find(isId))
  updatePrevNext(currentIndex)
}

router.beforeEach((to, from, next) => {
  getDetail()
  next()
})

const shareIconSize = computed(() => {
  return isDesktop.value ? '44' : '28'
})
const arrowIconSize = computed(() => {
  return isDesktop.value ? '28' : '24'
})

function getTime(timestamp) {
  const date = new Date(timestamp)
  const year = date.getFullYear()
  const month = date.getMonth() + 1
  const day = date.getDate()
  const weekday = [
    $t('info.sun'),
    $t('info.mom'),
    $t('info.tue'),
    $t('info.wed'),
    $t('info.thu'),
    $t('info.fri'),
    $t('info.sat'),
  ][date.getDay()]
  let hour = date.getHours()
  const amPm = hour < 12 ? $t('info.am') : $t('info.pm')
  hour = hour % 12 || 12

  const minute = date.getMinutes()
  const dateFormat = $t('info.dateFormat', { year, month, day })
  const dateFormatResult = dateFormat + ` ${weekday} ${amPm}${hour}:${minute.toString().padStart(2, '0')}`
  return dateFormatResult
}

const { copy } = useCopyToClipboard()
function shareLink(i) {
  copy(`${location.origin}/blog/${i}`)
}

function handleImageError() {
  detailData.value.cover_img = ErrorNodataImage
}

// Jsonld 佈置
const schema = shallowRef(null)
watch(
  detailData,
  (v) => {
    schema.value = {
      '@context': 'https://schema.org',
      '@type': 'BlogPosting',
      headline: v?.title,
      articleBody: v?.content,
      datePublished: v?.timestamp,
      image: v?.cover_img,
      publisher: {
        '@type': 'Organization',
        name: 'Fantasi',
        logo: {
          '@type': 'ImageObject',
          url: import.meta.env.VITE_APP_URL + import.meta.env.VITE_APP_OG_IMAGE,
        },
      },
      mainEntityOfPage: {
        '@type': 'WebPage',
        '@id': `https://www.fantasi.one/blog/${id.value}`,
      },
    }
  },
  { immediate: true },
)
</script>
<style lang="scss" scoped>
@import '@/assets/styles/loading-skeleton.scss';

.px- {
  &ctn {
    padding: 0 8.3334%;
  }
  &atc {
    padding: 0 16.67%;
  }
}
.img-container {
  width: 100%;
  position: relative;
  padding-top: calc(100% * 36.05 / 60);
  & img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 0.625rem;
    -webkit-user-drag: none;
  }
}
.err {
  background: linear-gradient(
    180deg,
    rgb(var(--v-theme-primary-gradient-from), 0.25) 0%,
    rgb(var(--v-theme-primary-gradient-to), 0.25) 100%
  );
  object-fit: none !important;
}
.load {
  border-radius: 0.625rem;
  @include loading-skeleton;
}
.h_ {
  &50 {
    height: 3.125rem;
  }
  &200 {
    height: 12.5rem;
  }
  &450 {
    height: 28.125rem;
  }
}
.scaleX {
  transform: scaleX(-1);
}
.ellipsis-multiple {
  text-overflow: ellipsis;
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.content {
  ::v-deep(h1) {
    font-size: 1.125rem;
    line-height: 140%;
  }
  ::v-deep(h2) {
    font-size: 1rem;
    line-height: 140%;
  }
  ::v-deep(h3) {
    font-size: 0.875rem;
    line-height: 140%;
  }
  ::v-deep(a) {
    font-size: 0.875rem;
    line-height: 140%;
    font-weight: 500;
    color: rgb(var(--v-theme-primary));
  }
  ::v-deep(strong, b) {
    font-size: 0.875rem;
    line-height: 140%;
  }
  ::v-deep(ul, li) {
    font-size: 0.875rem;
    line-height: 140%;
  }
}
</style>
